package lovedna.event;
import lovedna.event.Event;

/**
 * ...
 * @author liwei
 */

class EventDispatcher implements IEventDispatcher
{

	private var _listener:Hash<Array<Dynamic->Void>>;
	public function new() 
	{
		_listener = new Hash<Array<Dynamic->Void>>();
	}
	private function getList(type:String):Array < Dynamic->Void > {
		return _listener.get(type);
	}
	
	/* INTERFACE lovedna.event.IEventDispatcher */
	
	public function addEventListener(type:String, listener:Dynamic -> Void):Void 
	{
		var list:Array < Dynamic->Void > = getList(type);
		if (list == null) {
			list = new Array<Dynamic->Void>();
		}
		var len:Int = list.length;
		for (i in 0...len) {
			if (list[i] == listener) {
				return;
			}
		}
		list.push(listener);
		_listener.set(type, list);
	}
	
	public function dispatchEvent(event:Event):Bool 
	{
		var type:String = event.type;
		var list:Array < Dynamic->Void > = getList(type);
		if (list == null) return false;
		var len:Int = list.length;
		for (i in 0...len) {
			var listener:Dynamic->Void = list[i];
			listener(event);
		}
		return true;
	}
	
	public function hasEventListener(type:String,?listener:Dynamic->Void):Bool 
	{
		var list:Array < Dynamic->Void > = getList(type);
		if (list == null) return false;
		var len:Int = list.length;
		if (listener == null) {
			return len > 0;
		}
		for (i in 0...len) {
			var call:Dynamic->Void = list[i];
			if (call == listener) {
				return true;
			}
		}
		return false;
	}
	
	public function removeEventListener(type:String, listener:Dynamic -> Void):Void 
	{
		if (listener == null) {
			return;
		}
		var list:Array < Dynamic->Void > = getList(type);
		if (list == null) return;
		var len:Int = list.length;
		while (len-->0) {
			var call:Dynamic->Void = list[len];
			if (call == listener) {
				list.splice(len, 1);
			}
		}
	}
	
}